package com.nanchen.compressimage;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Environment;
import ohos.media.image.ImageSource;
import ohos.media.image.common.ImageFormat;
import ohos.security.SystemPermission;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import com.nanchen.compresshelper.CompressHelper;

public class MainAbility extends Ability {
    public static final int REQUEST_CODE = 1000;
    public static final String REQUEST_FILE_PATH = "camera_file";
    private final String TAG = "MainAbility";
    private Button takeBtn;
    private Button compressBtn;
    private Text originPixTxt;
    private Image compressImg;
    private Text compressPixTxt;
    private Image originImg;
    private File originFile;
    private File compressFile;
    private String filePath;
    private String phontoPath;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_main_layout);
        takeBtn = (Button) findComponentById(ResourceTable.Id_takePhoto);
        compressBtn = (Button) findComponentById(ResourceTable.Id_compress);
        originImg = (Image) findComponentById(ResourceTable.Id_img_origin);
        compressImg = (Image) findComponentById(ResourceTable.Id_img_compress);
        originPixTxt = (Text) findComponentById(ResourceTable.Id_txt_origin);
        compressPixTxt = (Text) findComponentById(ResourceTable.Id_txt_compress);
        initData();
        findComponentById(ResourceTable.Id_get_raw_file).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                getRawfile();
            }
        });
        findComponentById(ResourceTable.Id_compress_raw_file).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                compressRaw(component);
                compressImg.setBackground(null);
            }
        });
        takeBtn.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                jump2CamoraAbility();
            }
        });
        compressBtn.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (phontoPath == null || phontoPath.length() <= 0) {
                    return;
                }
                originFile = new File(phontoPath);
                compress(component);
            }
        });
    }

    private void initData() {
        filePath = getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath();
        File file = new File(filePath);
        if (!file.exists()) {
            boolean isexit = file.mkdirs();
        }
    }

    private void jump2CamoraAbility() {
        Intent secondIntent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName(getBundleName())
                .withAbilityName(CameraAbility.class.getName())
                .build();
        secondIntent.setOperation(operation);
        startAbilityForResult(secondIntent, REQUEST_CODE);
    }

    private void getRawfile() {
        originFile = new File(filePath + File.separator + "raw.jpg");
        try (
                InputStream initialStream = getResourceManager().getRawFileEntry("resources/rawfile/timg.jpg").openRawFile();
                OutputStream outStream = new FileOutputStream(originFile)
        ) {
            byte[] buffer = new byte[8 * 1024];
            int bytesRead;
            while ((bytesRead = initialStream.read(buffer)) != -1) {
                outStream.write(buffer, 0, bytesRead);
            }
        } catch (Exception ex) {
            Logger.getLogger(MainAbility.class.getName()).log(Level.SEVERE, ex.getMessage());
        }
        originImg.setPixelMap(ImageSource.create(originFile, null).createPixelmap(null));
        originPixTxt.setText(String.format("Size : %s", getReadableFileSize(originFile.length())));
        originImg.setBackground(null);
    }

    private void compressRaw(Component component) {
        originFile = new File(filePath + File.separator + "raw.jpg");
        compress(component);
    }

    public void compress(Component component) {
        if (!originFile.exists()) {
            return;
        }
        originPixTxt.setText(String.format("Size : %s", getReadableFileSize(originFile.length())));
        // 默认的压缩方法，多张图片只需要直接加入循环即可
        compressFile = CompressHelper.getDefault(getApplicationContext()).compressToFile(originFile);
        String yourFileName = "test";
        // 你也可以自定义压缩
        compressFile = new CompressHelper.Builder(this)
                .setMaxWidth(720)  // 默认最大宽度为720
                .setMaxHeight(960) // 默认最大高度为960
                .setQuality(80)    // 默认压缩质量为80
                .setCompressFormat(ImageFormat.ComponentType.JPEG) // 设置默认压缩为jpg格式
                .setFileName(yourFileName) // 设置你的文件名
                .setDestinationDirectoryPath(filePath)
                .build()
                .compressToFile(originFile);
        compressImg.setPixelMap(ImageSource.create(compressFile, null).createPixelmap(null));
        compressPixTxt.setText(String.format("Size : %s", getReadableFileSize(compressFile.length())));
    }

    private void requestPermissions() {
        if (verifyCallingPermission(SystemPermission.CAMERA) != 0) {
            String[] permissions = this.getPermissionArrays();
            if (permissions != null) {
                List<String> permissionFilters = (List) Arrays.stream(permissions).filter((permission) -> {
                    return this.verifySelfPermission(permission) != 0;
                }).collect(Collectors.toList());
                this.requestPermissionsFromUser((String[]) permissionFilters.toArray(new String[permissionFilters.size()]), 0);
            }
        }
    }

    public String[] getPermissionArrays() {
        return new String[]{SystemPermission.CAMERA};
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent data) {
        super.onAbilityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && resultCode == REQUEST_CODE) {
            if (data == null) {
                return;
            }
            try {
                phontoPath = data.getStringParam(REQUEST_FILE_PATH);
                if (phontoPath == null || phontoPath.length() <= 0) {
                    return;
                }
                originFile = new File(phontoPath);
                originImg.setPixelMap(ImageSource.create(originFile, null).createPixelmap(null));
                originPixTxt.setText(String.format("Size : %s", getReadableFileSize(originFile.length())));
                clearImage();
            } catch (Exception ex) {
                showError("Failed to read picture data!");
                Logger.getLogger(MainAbility.class.getName()).log(Level.SEVERE, ex.getMessage());
            }
        }
    }

    public void showError(String errorMessage) {
        new ToastDialog(this).setText(errorMessage).show();
    }

    private RgbColor getRandomColor() {
        SecureRandom rand = new SecureRandom();
        return new RgbColor(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
    }

    private void clearImage() {
        ShapeElement element = new ShapeElement();
        element.setRgbColor(getRandomColor());
        originImg.setBackground(element);
        originImg.setImageElement(null);
        element = new ShapeElement();
        element.setRgbColor(getRandomColor());
        compressImg.setBackground(element);
        compressPixTxt.setText("Size : -");
    }

    public String getReadableFileSize(long size) {
        if (size <= 0) {
            return "0";
        }
        final String[] units = new String[]{"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
        return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups)) + " " + units[digitGroups];
    }
}
